home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
- * Copying of this file is granted according to the provisions
- * specified in the file COPYING which must accompany this file.
- */
-
-
- /*
- * math.c
- */
-
- #include "tex.h"
- #include "heap.h"
- #include "eq.h"
- #include "scan.h"
- #include "evalstack.h"
- #include "arith.h"
- #include "str.h"
- #include "box.h"
- #include "tfm.h"
- #include "print.h"
- #include "pack.h"
- #include "math.h"
-
- twoh empty_field;
-
- ptr
- new_style (s)
- int s;
- {
- ptr p;
-
- p = get_node(STYLE_NODE_SIZE);
- type(p) = STYLE_NODE;
- subtype(p) = s;
- width(p)= 0;
- depth(p) = 0;
-
- return p;
- }
-
- ptr
- new_choice ()
- {
- ptr p;
-
- p = get_node(STYLE_NODE_SIZE);
- type(p) = CHOICE_NODE;
- subtype(p) = 0;
- display_mlist(p) = NULL;
- text_mlist(p) = NULL;
- script_mlist(p) = NULL;
- script_script_mlist(p) = NULL;
-
- return p;
- }
-
- ptr
- new_noad ()
- {
- ptr p;
-
- p = get_node(NOAD_SIZE);
- type(p) = ORD_NOAD;
- subtype(p) = NORMAL;
- mem[nucleus(p)].hh = empty_field;
- mem[subscr(p)].hh = empty_field;
- mem[supscr(p)].hh = empty_field;
-
- return p;
- }
-
- print_fam_and_char (p)
- ptr p;
- {
- print_esc("fam");
- print_int(fam(p));
- print_char(' ');
- print_ASCII(qo(character(p)));
- }
-
- print_delimiter (p)
- ptr p;
- {
- val a;
-
- a = small_fam(p) * 256 + qo(small_char(p));
- a = a * 0x1000 + large_fam(p) * 256 + qo(large_char(p));
- if (a < 0)
- print_val(a);
- else print_hex(a);
- }
-
- print_subsidiary_data (p, c)
- ptr p;
- ascii c;
- {
- if (cur_length() >= depth_threshold) {
- if (math_type(p) != EMPTY)
- print(" []");
- return;
- }
- append_char(c);
- temp_ptr = p;
- switch (math_type(p))
- {
- case MATH_CHAR:
- print_ln();
- print_current_string();
- print_fam_and_char(p);
- break;
-
- case SUB_BOX:
- show_info();
- break;
-
- case SUB_MLIST:
- if (info(p) == NULL) {
- print_ln();
- print_current_string();
- print("{}");
- } else show_info();
- break;
- }
- flush_char();
- }
-
- print_style (c)
- int c;
- {
- switch (c / 2)
- {
- case 0:
- print_esc("displaystyle");
- break;
-
- case 1:
- print_esc("textstyle");
- break;
-
- case 2:
- print_esc("scriptstyle");
- break;
-
- case 3:
- print_esc("scriptscriptstyle");
- break;
-
- default:
- print("Unknown style!");
- break;
- }
- }
-
- print_size (s)
- int s;
- {
- if (s == 0)
- print_esc("textfont");
- else if (s == SCRIPT_SIZE)
- print_esc("scriptfont");
- else print_esc("scriptscriptfont");
- }
-
- show_normal_noad (p)
- ptr p;
- {
- switch (type(p))
- {
- case ORD_NOAD:
- print_esc("mathord");
- break;
-
- case OP_NOAD:
- print_esc("mathop");
- break;
-
- case BIN_NOAD:
- print_esc("mathbin");
- break;
-
- case REL_NOAD:
- print_esc("mathrel");
- break;
-
- case OPEN_NOAD:
- print_esc("mathopen");
- break;
-
- case CLOSE_NOAD:
- print_esc("mathclose");
- break;
-
- case PUNCT_NOAD:
- print_esc("mathpunct");
- break;
-
- case INNER_NOAD:
- print_esc("mathinner");
- break;
-
- case OVER_NOAD:
- print_esc("overline");
- break;
-
- case UNDER_NOAD:
- print_esc("underline");
- break;
-
- case VCENTER_NOAD:
- print_esc("vcenter");
- break;
-
- case RADICAL_NOAD:
- print_esc("radical");
- print_delimiter(left_delimiter(p));
- break;
-
- case ACCENT_NOAD:
- print_esc("accent");
- print_fam_and_char(accent_chr(p));
- break;
-
- case LEFT_NOAD:
- print_esc("left");
- print_delimiter(nucleus(p));
- break;
-
- case RIGHT_NOAD:
- print_esc("right");
- print_delimiter(nucleus(p));
- break;
-
- }
- if (subtype(p) != NORMAL)
- if (subtype(p) == LIMITS)
- print_esc("limits");
- else print_esc("nolimits");
- if (type(p) < LEFT_NOAD)
- print_subsidiary_data(nucleus(p), '.');
- print_subsidiary_data(supscr(p), '^');
- print_subsidiary_data(subscr(p), '_');
- }
-
- show_fraction_noad (p)
- ptr p;
- {
- print_esc("fraction, thickness ");
- if (thickness(p) == DEFAULT_CODE)
- print("= default");
- else print_scaled(thickness(p));
- if (small_fam(left_delimiter(p)) != 0 ||
- small_char(left_delimiter(p)) != MIN_QUARTERWORD ||
- large_fam(left_delimiter(p)) != 0 ||
- large_char(left_delimiter(p)) != MIN_QUARTERWORD) {
- print(", left-delimiter ");
- print_delimiter(left_delimiter(p));
- }
- if (small_fam(right_delimiter(p)) != 0 ||
- small_char(right_delimiter(p)) != MIN_QUARTERWORD ||
- large_fam(right_delimiter(p)) != 0 ||
- large_char(right_delimiter(p)) != MIN_QUARTERWORD) {
- print(", right-delimiter ");
- print_delimiter(right_delimiter(p));
- }
- print_subsidiary_data(numerator(p), '\\');
- print_subsidiary_data(denominator(p), '/');
- }
-
- show_choice_node (p)
- ptr p;
- {
- print_esc("mathchoice");
- append_char('D');
- show_node_list(display_mlist(p));
- flush_char();
- append_char('T');
- show_node_list(text_mlist(p));
- flush_char();
- append_char('S');
- show_node_list(script_mlist(p));
- flush_char();
- append_char('s');
- show_node_list(script_script_mlist(p));
- flush_char();
- }
-
- ptr
- fraction_rule (t)
- scal t;
- {
- ptr p;
-
- p = new_rule();
- height(p) = t;
- depth(p) = 0;
-
- return p;
- }
-
- ptr
- overbar (b, k, t)
- ptr b;
- scal k;
- scal t;
- {
- ptr p;
- ptr q;
-
- p = new_kern(k);
- link(p) = b;
- q = fraction_rule(t);
- link(q) = p;
- p = new_kern(t);
- link(p) = q;
- return (vpack(p, NATURAL));
- }
-
- ptr
- var_delimiter (d, s, v)
- ptr d;
- int s;
- scal v;
- {
- ptr b;
- qword c;
- fnt f;
- fnt g;
- int m;
- int n;
- fourq q;
- fourq r;
- scal u;
- scal w;
- qword x;
- qword y;
- int z;
- byte hd;
- bool large_attempt;
-
- f = NULL_FONT;
- w = 0;
- large_attempt = FALSE;
- z = small_fam(d);
- x = small_char(d);
- loop {
- if (z != 0 || x != MIN_QUARTERWORD) {
- z = z + s + 16;
- do {
- z = z - 16;
- g = fam_fnt(z);
- if (g != NULL_FONT) {
- y = x;
- contin:
- if (qo(y) >= font_bc[g] && qo(y) <= font_ec[g]) {
- q = char_info(g, y);
- if (char_exists(q)) {
- if (char_tag(q) == EXT_TAG) {
- f = g;
- c = y;
- goto found;
- }
- hd = height_depth(q);
- u = char_height(g, hd) + char_depth(g, hd);
- if (u > w) {
- f = g;
- c = y;
- w = u;
- if (u >= v)
- goto found;
- }
- if (char_tag(q) == LIST_TAG) {
- y = rem_byte(q);
- goto contin;
- }
- }
- }
- }
- } while (z >= 16);
- }
- if (large_attempt)
- goto found;
- large_attempt = TRUE;
- z = large_fam(d);
- x = large_char(d);
- }
-
- found:
- if (f != NULL_FONT) {
- if (char_tag(q) == EXT_TAG) {
- b = new_null_box();
- type(b) = VLIST_NODE;
- r = font_info[exten_base[f] + rem_byte(q)].qqqq;
- c = ext_rep(r);
- u = height_plus_depth(f, c);
- w = 0;
- q = char_info(f, c);
- width(b) = char_width(f, q) + char_italic(f, q);
- c = ext_bot(r);
- if (c != MIN_QUARTERWORD)
- w += height_plus_depth(f, c);
- c = ext_mid(r);
- if (c != MIN_QUARTERWORD)
- w += height_plus_depth(f, c);
- c = ext_top(r);
- if (c != MIN_QUARTERWORD)
- w += height_plus_depth(f, c);
- n = 0;
- if (u > 0) {
- while (w < v) {
- w = w + u;
- incr(n);
- if (ext_mid(r) != MIN_QUARTERWORD)
- w = w + u;
- }
- }
- c = ext_bot(r);
- if (c != MIN_QUARTERWORD)
- stack_into_box(b, f, c);
- c = ext_rep(r);
- for (m = 1; m <= n; incr(m))
- stack_into_box(b, f, c);
- c = ext_mid(r);
- if (c != MIN_QUARTERWORD) {
- stack_into_box(b, f, c);
- c = ext_rep(r);
- for (m = 1; m <= n; incr(m))
- stack_into_box(b, f, c);
- }
- c = ext_top(r);
- if (c != MIN_QUARTERWORD)
- stack_into_box(b, f, c);
- depth(b) = w - height(b);
- } else
- b = char_box(f, c);
- } else {
- b = new_null_box();
- width(b) = null_delimiter_space;
- }
- shift_amount(b) = half(height(b) - depth(b)) - axis_height(s);
- return b;
- }
-
- ptr
- char_box (f, c)
- fnt f;
- qword c;
- {
- ptr b;
- ptr p;
- fourq q;
- byte hd;
-
- q = char_info(f, c);
- hd = height_depth(q);
- b = new_null_box();
- width(b) = char_width(f, q) + char_italic(f, q);
- height(b) = char_height(f, hd);
- depth(b) = char_depth(f, hd);
- p = get_avail();
- character(p) = c;
- font(p) = f;
- list_ptr(b) = p;
-
- return b;
- }
-
- stack_into_box (b, f, c)
- ptr b;
- fnt f;
- qword c;
- {
- ptr p;
-
- p = char_box(f, c);
- link(p) = list_ptr(b);
- list_ptr(b) = p;
- height(b) = height(p);
- }
-
- scal
- height_plus_depth (f, c)
- fnt f;
- qword c;
- {
- fourq q;
- byte hd;
-
- q = char_info(f, c);
- hd = height_depth(q);
- return (char_height(f, hd) + char_depth(f, hd));
- }
-
- ptr
- rebox (b, w)
- ptr b;
- scal w;
- {
- fnt f;
- ptr p;
- scal v;
-
- if (width(b) != w && list_ptr(b) != NULL) {
- if (type(b) == VLIST_NODE)
- b = hpack(b, NATURAL);
- p = list_ptr(b);
- if (is_char_node(p) && link(p) == NULL) {
- f = font(p);
- v = char_width(f, char_info(f, character(p)));
- if (v != width(b))
- link(p) = new_kern(width(b) - v);
- }
- free_node(b, BOX_NODE_SIZE);
- b = new_glue(ss_glue);
- link(b) = p;
- while (link(p) != NULL)
- p = link(p);
- link(p) = new_glue(ss_glue);
- return (hpack(b, w, EXACTLY));
- } else {
- width(b) = w;
- return b;
- }
- }
-
- #define mu_mult(x) \
- nx_plus_y(n, x, xn_over_d(x, f, 0200000L))
-
- ptr
- math_glue (g, m)
- ptr g;
- scal m;
- {
- scal f;
- val n;
- ptr p;
-
- n = x_over_n(m, 0200000L);
- f = remainder;
- p = get_node(GLUE_SPEC_SIZE);
- width(p) = mu_mult(width(g));
- stretch_order(p) = stretch_order(g);
- if (stretch_order(p) == NORMAL)
- stretch(p) = mu_mult(stretch(g));
- else stretch(p) = stretch(g);
- shrink_order(p) = shrink_order(g);
- if (shrink_order(p) == NORMAL)
- shrink(p) = mu_mult(shrink(g));
- else shrink(p) = shrink(g);
-
- return p;
- }
-
- math_kern (p, m)
- ptr p;
- scal m;
- {
- scal f;
- val n;
-
- if (subtype(p) == MU_GLUE) {
- n = x_over_n(m, 0200000L);
- f = remainder;
- width(p) = mu_mult(width(p));
- subtype(p) = NORMAL;
- }
- }
-
- flush_math ()
- {
- flush_node_list(link(head));
- flush_node_list(incompleat_noad);
- link(head) = NULL;
- tail = head;
- incompleat_noad = NULL;
- }
-